package com.tarena.lbs.business.servcie.impl;

import com.github.pagehelper.PageInfo;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.attach.pojo.param.PicUpdateParam;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.business.constant.BusinessTypes;
import com.tarena.lbs.business.dao.repository.BusinessRepository;
import com.tarena.lbs.business.pojo.param.BusinessParam;
import com.tarena.lbs.business.pojo.param.BusinessUpdateStatusParam;
import com.tarena.lbs.business.pojo.po.BusinessPO;
import com.tarena.lbs.business.pojo.query.BusinessQuery;
import com.tarena.lbs.business.pojo.vo.BusinessStoreVO;
import com.tarena.lbs.business.pojo.vo.BusinessVO;
import com.tarena.lbs.business.pojo.vo.StoreVO;
import com.tarena.lbs.business.servcie.BusinessService;
import com.tarena.lbs.common.enums.BusinessResultEnum;
import com.tarena.lbs.common.enums.Roles;
import com.tarena.lbs.common.principle.UserPrinciple;
import com.tarena.lbs.common.utils.AuthenticationContextUtils;
import com.tarena.lbs.user.api.UserApi;
import com.tarena.lbs.user.api.pojo.dto.AdminDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class BusinessServiceImpl implements BusinessService {
    @DubboReference
    private AttachApi attachApi;

    @Autowired
    private BusinessRepository businessRepository;

    @DubboReference
    private UserApi userApi;

    //新增商家
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(BusinessParam param) throws BusinessException {
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        if (userPrinciple==null){
            throw new BusinessException(BusinessResultEnum.USER_NOT_LOGIN);
        }
        //1.检查当前登录用户的角色是否符合我当前业务的角色要求
        // ADMIN 平台管理员 才能创建商家  SHOP 商家账号 能创建店铺
        checkRole(Roles.ADMIN);
        //2.验证检查幂等 是否存在相同名称的商家数据
        BusinessPO businessPO = businessRepository.getBusinessByName(param.getBusinessName());

        if (param.getId() != null){
            if (!businessPO.getId().equals(param.getId())){
                throw new BusinessException(BusinessResultEnum.BUSINESS_NAME_EXISTS);
            }
            BusinessPO po = businessRepository.getBusinessById(param.getId());
            if (po!=null){
                throw new BusinessException(BusinessResultEnum.BUSINESS_NOT_EXISTS);
            }
            updateBusiness(param);
            bindPictures(param.getId(),param);
        }
        else {
            if (businessPO!=null){
                throw new BusinessException(BusinessResultEnum.BUSINESS_NAME_EXISTS);
            }
            //3.幂等验证正常 可以新增 封装 数据对象PO 执行save新增
            Integer id=insertBusiness(param);
            //4.新增之后的商家 有了id 定义 type 100营业执照 200logo调用图片绑定
            bindPictures(id,param);
        }
    }

    //新增商家
    private Integer insertBusiness(BusinessParam param) {
        BusinessPO businessPO =new BusinessPO();
        BeanUtils.copyProperties(param,businessPO);
        businessPO.setEntryTime(new Date());
        businessRepository.insertBusiness(businessPO);
        return businessPO.getId();
    }

    //更新商家
    private void updateBusiness(BusinessParam param) {
        BusinessPO businessPO =new BusinessPO();
        BeanUtils.copyProperties(param,businessPO);
        businessRepository.updateById(businessPO);
    }

    //商家列表查询
    @Override
    public PageResult<BusinessVO> pageList(BusinessQuery query) throws BusinessException {
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        if (userPrinciple==null){
            throw new BusinessException(BusinessResultEnum.USER_NOT_LOGIN);
        }
        //1.平台管理员可以查询所有商家列表
        //商家管理员可以查询当前商家下的所有商家
        if (Roles.SHOP.equals(userPrinciple.getRole())) {
            AdminDto adminDto = userApi.getAdminById(userPrinciple.getId());
            if (adminDto == null) {
                throw new BusinessException(BusinessResultEnum.BUSINESS_NOT_EXISTS);
            }
            query.setBusinessId(adminDto.getBusinessId());
        }
        // 分页查询
        PageResult<BusinessVO> voPage = new PageResult<>(query);
        // 获取分页查询结果
        List<BusinessPO> businessPOS = businessRepository.selectPage(query);
        // 使用PageInfo获取总记录数
        PageInfo<BusinessPO> pageInfo = new PageInfo<>(businessPOS);
        voPage.setTotal(pageInfo.getTotal());
        // 将分页信息中的页码设置到分页结果对象中
        voPage.setPageNo(pageInfo.getPageNum());
        // 将分页信息中的每页数量设置到分页结果对象中
        voPage.setPageSize(pageInfo.getPageSize());
        // 封装VO
        List<BusinessVO> businessVOS = new ArrayList<>();
        // 循环转换
        for (BusinessPO businessPO : businessPOS) {
            // 转换
            BusinessVO businessVO = new BusinessVO();
            // 复制
            BeanUtils.copyProperties(businessPO,businessVO);
            // 设置logo
            businessVOS.add(businessVO);
        }
        // 设置分页结果
        voPage.setObjects(businessVOS);
        return voPage;
    }

    //商家详情查询
    @Override
    public BusinessStoreVO selectByBusinessId(Integer businessId) {
        // 1. 参数校验
        if (businessId == null) {
            return null;
        }
        // 2. 查询商家基本信息
        BusinessPO businessPO = businessRepository.getBusinessById(businessId);
        if (businessPO == null) {
            return null;
        }
        // 3. 创建并填充BusinessStoreVO对象
        BusinessStoreVO vo = new BusinessStoreVO();
        BeanUtils.copyProperties(businessPO, vo);
        // 4. 查询该商家下的所有店铺列表

        //填充商家行业名称
        vo.setIndustryName(getIndustryNameByType(businessPO.getIndustryType()));

        List<StoreVO> storeVOList = businessRepository.getStoreByBusinessId(businessId);
        vo.setStoreVOList(storeVOList);
        // 5. 设置商家logo
        vo.setBusinessLogo(businessPO.getBusinessLogo());
        return vo;

    }

    @Override
    public BusinessVO selectById(Integer businessId) throws BusinessException {
        BusinessPO po  = businessRepository.selectById(businessId);
        if (po==null){
            throw new BusinessException(BusinessResultEnum.BUSINESS_NOT_EXISTS);
        }
        BusinessVO vo = new BusinessVO();
        BeanUtils.copyProperties(po,vo);
        vo.setIndustryName(getIndustryNameByType(po.getIndustryType()));
        return vo;
    }

    @Override
    public void updateStatus(BusinessUpdateStatusParam param) throws BusinessException {
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        if (userPrinciple==null){
            throw new BusinessException(BusinessResultEnum.USER_NOT_LOGIN);
        }
        //1.检查当前登录用户的角色是否符合我当前业务的角色要求
        // ADMIN 平台管理员 才能创建商家  SHOP 商家账号 能创建店铺
        checkRole(Roles.ADMIN);
        businessRepository.updateStatus(param);
    }

    //行业名称
    private String getIndustryNameByType(Integer industryType) {
        switch (industryType) {
            case 1:
                return "餐饮";
            case 2:
                return "旅游";
            case 3:
                return "商务服务";
            case 4:
                return "其他";
            default:
                return "";
        }
    }

    //图片绑定
    private void bindPictures(Integer businessId, BusinessParam param) throws BusinessException {
        //商家新增 图片 要绑定两张 一张营业执照 一张logo
        //准备一下 接口的入参
        List<PicUpdateParam> picParams=new ArrayList<>();
        //准备一个PicUpdateParam 存储营业执照 的绑定参数
        PicUpdateParam licenseParam=new PicUpdateParam();
        //bizType 100 表示商家营业执照
        licenseParam.setBusinessType(BusinessTypes.BIZ_LICENSE);
        //bizId 商家id
        licenseParam.setBusinessId(businessId);
        //可以在对象里绑定图片id或者图片fileUuid 当前业务无法获取图片id只能获取fileUuid
        //http://localhost:9081/static/19fh93gr931h10rf3h29r.png 最后的值是fileUuid的拼接 19fh93gr931h10rf3h29r.png
        String licenseUrl = param.getBusinessLicense();
        licenseParam.setFileUuid(getFileUuidFromUrl(licenseUrl));
        //准备第二个绑定图片的入参元素 绑定logo
        PicUpdateParam logoParam=new PicUpdateParam();
        logoParam.setBusinessType(BusinessTypes.BIZ_LOGO);
        logoParam.setBusinessId(businessId);
        String logoUrl = param.getBusinessLogo();
        logoParam.setFileUuid(getFileUuidFromUrl(logoUrl));
        //将营业执照图片数据 和log图片数据放到list中
        picParams.add(licenseParam);
        picParams.add(logoParam);
        boolean result = attachApi.batchUpdateBusiness(picParams);
        Asserts.isTrue(!result,new BusinessException("-2","业务绑定失败"));
    }

    //获取fileUuid
    private String getFileUuidFromUrl(String licenseUrl) {
        return licenseUrl.substring(licenseUrl.lastIndexOf("/")+1);
    }

    //验证当前登录用户角色
    private void checkRole(Roles roles) throws BusinessException {
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        if (!userPrinciple.getRole().equals(roles)){
            throw new BusinessException(BusinessResultEnum.USER_ROLE_NOT_MATCH);
        }
    }
}
